package com.ruoyi.framework.shiro.web.filter.token;

import com.alibaba.fastjson.JSON;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.framework.shiro.token.JwtToken;
import com.ruoyi.framework.shiro.token.JwtUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class JwtAuthFilter extends AuthenticatingFilter {
    Logger log = LoggerFactory.getLogger(JwtAuthFilter.class);

    private JwtUtils jwtUtils;


    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        String token = getRequestToken((HttpServletRequest) request);

        // 1. 没有token的请求
        if (StringUtils.isEmpty(token)) {
            return true;    // 继续其他过滤器
        }

        // 2. 已经认证过的请求 是检查当前 Subject 是否认证，但它不会验证 token 是否被篡改。
        //if (SecurityUtils.getSubject().isAuthenticated()) {
        //     return true;    // 已认证，直接通过
        // }

        // 3. 有token但未认证的请求
        return false;       // 进入onAccessDenied验证token
    }


    @Override
    protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
        // 从请求头获取token
        String token = getRequestToken((HttpServletRequest) request);
        if (StringUtils.isEmpty(token)) {
            return null;
        }
        return new JwtToken(token);
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        String token = getRequestToken((HttpServletRequest) request);
        if (StringUtils.isEmpty(token)) {
            // 如果没有token，交给下一个过滤器处理（可能是cookie认证）
            return true;
        }
        // 这里应该验证token 有token但无效，返回true继续尝试Cookie认证
        if (!jwtUtils.validateToken(token)) {
            HttpServletResponse httpResponse = (HttpServletResponse) response;
            httpResponse.setContentType("application/json;charset=UTF-8");
            // 创建统一返回格式
            AjaxResult result = AjaxResult.error(HttpStatus.UNAUTHORIZED.getReasonPhrase(), "token无效");
            // 将对象转换为JSON字符串
            String jsonStr = JSON.toJSONString(result);
            // 写入响应
            httpResponse.getWriter().write(jsonStr);
            return false;
        }

        try {
            executeLogin(request, response);
            // 登录成功，继续执行后续过滤器
            return true;
        } catch (AuthenticationException e) {
            // token验证失败，传给下一个过滤器
            log.info("token验证失败: "+ token);
            HttpServletResponse httpResponse = (HttpServletResponse) response;
            httpResponse.setContentType("application/json;charset=UTF-8");
            // 创建统一返回格式
            AjaxResult result = AjaxResult.error(HttpStatus.UNAUTHORIZED.getReasonPhrase(), "token无效");
            // 将对象转换为JSON字符串
            String jsonStr = JSON.toJSONString(result);
            // 写入响应
            httpResponse.getWriter().write(jsonStr);
            return false;
        }
    }

    private String getRequestToken(HttpServletRequest request) {
        // 从请求头中获取token
        String token = request.getHeader("Authorization");
        if (StringUtils.isNotEmpty(token) && token.startsWith("Bearer ")) {
            token = token.substring(7);
        }
        return token;
    }

    public JwtUtils getJwtUtils() {
        return jwtUtils;
    }

    public void setJwtUtils(JwtUtils jwtUtils) {
        this.jwtUtils = jwtUtils;
    }
}